/**
 * ...
 * @author Tonypee
 */

package hxs;

import hxs.core.SignalBase;
import hxs.extras.Trigger;
import hxs.extras.Trigger;
import hxs.core.Info;
import hxs.core.SignalType;

class Signal extends SignalBase <Void->Void, Info->Void>
{

	public function new(?caller:Dynamic, ?bubbleId:String=null) 
	{ 
		super(caller, bubbleId); 
	}
	
	public function dispatch()
	{
		for (slot in slots) 
		{
			if (isMuted) return;
			if (slot.isMuted) continue;
			switch(slot.type)
			{
				case SignalType.NORMAL:slot.listener();
				case SignalType.ADVANCED:slot.listener(new Info(this, slot));
				case SignalType.VOID:slot.listener();
			}
			onFireSlot(slot);
		}
		
		if (this.bubbleId != null && this.target != null)
			bubble();
	}
	
	private function bubble()
	{
		var target:Dynamic = this.target.parent;
		while (target != null)
		{
			var fields = Type.getInstanceFields(Type.getClass(target));
			var index = Lambda.indexOf(fields, bubbleId);
			if (index != -1)
			{
				var f = Reflect.field(target, bubbleId);
				if (Std.is(f, Signal))
					cast(f, Signal).dispatch();
			}
			target = target.parent;
		}
	}
	
	public function getTrigger():Trigger
	{
		var _this = this;
		return new Trigger( function() _this.dispatch() );
	}
}